const BoxPointer = imports.ui.boxpointer;
const GnomeSession = imports.misc.gnomeSession;
const Main = imports.ui.main;
+const PopupMenu = imports.ui.popupMenu;
const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
const Util = imports.misc.util;
this.notification = notification;
- this._notificationClickedId = notification.connect('clicked', Lang.bind(this, this._notificationClicked));
+ this._notificationClickedId = notification.connect('clicked', Lang.bind(this, this.open));
this._notificationDestroyedId = notification.connect('destroy', Lang.bind(this,
function () {
if (this.notification == notification) {
},
// Default implementation is to do nothing, but subclasses can override
- _notificationClicked: function(notification) {
+ open: function(notification) {
},
// Default implementation is to destroy this source, but subclasses can override
this._sourceBox.add_actor(this._sourceIcon);
this._sourceBox.add_actor(this._sourceTitleBin, { expand: true });
this.actor.child = this._sourceBox;
+ this.rightClickMenu = new St.BoxLayout({ name: 'summary-right-click-menu',
+ vertical: true });
+
+ let item;
+
+ item = new PopupMenu.PopupMenuItem(_("Open"));
+ item.connect('activate', Lang.bind(this, function() {
+ source.open();
+ this.emit('right-click-menu-done-displaying');
+ }));
+ this.rightClickMenu.add(item.actor);
+
+ item = new PopupMenu.PopupMenuItem(_("Remove"));
+ item.connect('activate', Lang.bind(this, function() {
+ source.destroy();
+ this.emit('right-click-menu-done-displaying');
+ }));
+ this.rightClickMenu.add(item.actor);
+
+ let focusManager = St.FocusManager.get_for_stage(global.stage);
+ focusManager.add_group(this.rightClickMenu);
},
// getTitleNaturalWidth, getTitleWidth, and setTitleWidth include
this._sourceTitle.clutter_text.ellipsize = mode;
}
};
+Signals.addSignalMethods(SummaryItem.prototype);
function MessageTray() {
this._init();
this._summaryMotionId = 0;
- this._summaryNotificationBoxPointer = new BoxPointer.BoxPointer(St.Side.BOTTOM,
- { reactive: true,
- track_hover: true });
- this._summaryNotificationBoxPointer.actor.style_class = 'summary-notification-boxpointer';
- this.actor.add_actor(this._summaryNotificationBoxPointer.actor);
- this._summaryNotificationBoxPointer.actor.lower_bottom();
- this._summaryNotificationBoxPointer.actor.hide();
+ this._summaryBoxPointer = new BoxPointer.BoxPointer(St.Side.BOTTOM,
+ { reactive: true,
+ track_hover: true });
+ this._summaryBoxPointer.actor.style_class = 'summary-boxpointer';
+ this.actor.add_actor(this._summaryBoxPointer.actor);
+ this._summaryBoxPointer.actor.lower_bottom();
+ this._summaryBoxPointer.actor.hide();
this._summaryNotification = null;
this._summaryNotificationClickedId = 0;
+ this._summaryRightClickMenuClickedId = 0;
this._clickedSummaryItem = null;
+ this._clickedSummaryItemMouseButton = -1;
this._clickedSummaryItemAllocationChangedId = 0;
this._expandedSummaryItem = null;
this._summaryItemTitleWidth = 0;
this._focusGrabber = new FocusGrabber();
this._focusGrabber.connect('focus-grabbed', Lang.bind(this,
function() {
- if (this._summaryNotification)
+ if (this._summaryBoxPointer.bin.child)
this._lock();
}));
this._focusGrabber.connect('focus-ungrabbed', Lang.bind(this, this._unlock));
this._notificationState = State.HIDDEN;
this._notificationTimeoutId = 0;
this._notificationExpandedId = 0;
- this._summaryNotificationState = State.HIDDEN;
+ this._summaryBoxPointerState = State.HIDDEN;
this._summaryNotificationTimeoutId = 0;
this._summaryNotificationExpandedId = 0;
this._overviewVisible = Main.overview.visible;
Main.chrome.addActor(this.actor, { affectsStruts: false,
visibleInOverview: true });
Main.chrome.trackActor(this._notificationBin);
- Main.chrome.trackActor(this._summaryNotificationBoxPointer.actor);
+ Main.chrome.trackActor(this._summaryBoxPointer.actor);
global.gdk_screen.connect('monitors-changed', Lang.bind(this, this._setSizePosition));
this._onSummaryItemHoverChanged(summaryItem);
}));
- summaryItem.actor.connect('clicked', Lang.bind(this,
- function () {
- this._onSummaryItemClicked(summaryItem);
+ summaryItem.actor.connect('button-press-event', Lang.bind(this,
+ function (actor, event) {
+ this._onSummaryItemClicked(summaryItem, event);
}));
source.connect('destroy', Lang.bind(this, this._onSourceDestroy));
this._expandedSummaryItem.setEllipsization(Pango.EllipsizeMode.END);
},
- _onSummaryItemClicked: function(summaryItem) {
- if (!this._clickedSummaryItem || this._clickedSummaryItem != summaryItem)
+ _onSummaryItemClicked: function(summaryItem, event) {
+ let clickedButton = event.get_button();
+ if (!this._clickedSummaryItem ||
+ this._clickedSummaryItem != summaryItem ||
+ this._clickedSummaryItemMouseButton != clickedButton) {
this._clickedSummaryItem = summaryItem;
- else
+ this._clickedSummaryItemMouseButton = clickedButton;
+ } else {
this._unsetClickedSummaryItem();
+ }
this._updateState();
},
// leaving the tray. The tray is locked when the summary notification is visible anyway, but we
// should treat the mouse being over the summary notification as the tray being left for collapsing
// any expanded summary item other than the one related to the notification.
- if (this._summaryNotificationBoxPointer.bin.hover)
+ if (this._summaryBoxPointer.bin.hover)
return;
this._useLongerTrayLeftTimeout = false;
}
// Summary notification
- let haveSummaryNotification = this._clickedSummaryItem != null;
- let summaryNotificationIsMainNotification = (haveSummaryNotification &&
+ let haveClickedSummaryItem = this._clickedSummaryItem != null;
+ let summaryNotificationIsMainNotification = (haveClickedSummaryItem &&
this._clickedSummaryItem.source.notification == this._notification);
- let canShowSummaryNotification = this._summaryState == State.SHOWN;
- let wrongSummaryNotification = (haveSummaryNotification &&
+ let canShowSummaryBoxPointer = this._summaryState == State.SHOWN;
+ let wrongSummaryNotification = (this._clickedSummaryItemMouseButton == 1 &&
this._summaryNotification != this._clickedSummaryItem.source.notification);
-
- if (this._summaryNotificationState == State.HIDDEN) {
- if (haveSummaryNotification && !summaryNotificationIsMainNotification && canShowSummaryNotification)
- this._showSummaryNotification();
- } else if (this._summaryNotificationState == State.SHOWN) {
- if (!haveSummaryNotification || !canShowSummaryNotification || wrongSummaryNotification)
- this._hideSummaryNotification();
+ let wrongSummaryRightClickMenu = (this._clickedSummaryItemMouseButton == 3 &&
+ this._summaryBoxPointer.bin.child != this._clickedSummaryItem.rightClickMenu);
+ let wrongSummaryBoxPointer = (haveClickedSummaryItem &&
+ (wrongSummaryNotification || wrongSummaryRightClickMenu));
+
+ if (this._summaryBoxPointerState == State.HIDDEN) {
+ if (haveClickedSummaryItem && !summaryNotificationIsMainNotification && canShowSummaryBoxPointer)
+ this._showSummaryBoxPointer();
+ } else if (this._summaryBoxPointerState == State.SHOWN) {
+ if (!haveClickedSummaryItem || !canShowSummaryBoxPointer || wrongSummaryBoxPointer)
+ this._hideSummaryBoxPointer();
}
// Tray itself
this._expandedSummaryItemTitleWidth = this._summaryItemTitleWidth;
},
- _showSummaryNotification: function() {
- this._summaryNotification = this._clickedSummaryItem.source.notification;
- this._summaryNotificationClickedId = this._summaryNotification.connect('done-displaying',
- Lang.bind(this, this._escapeTray));
- let index = this._notificationQueue.indexOf(this._summaryNotification);
- if (index != -1)
- this._notificationQueue.splice(index, 1);
+ _showSummaryBoxPointer: function() {
+ if (this._clickedSummaryItemMouseButton == 1) {
+ let clickedSummaryItemNotification = this._clickedSummaryItem.source.notification;
+ let index = this._notificationQueue.indexOf(clickedSummaryItemNotification);
+ if (index != -1)
+ this._notificationQueue.splice(index, 1);
+
+ this._summaryNotification = clickedSummaryItemNotification;
+ this._summaryNotificationClickedId = this._summaryNotification.connect('done-displaying',
+ Lang.bind(this, this._escapeTray));
+ this._summaryBoxPointer.bin.child = this._summaryNotification.actor;
+ if (!this._summaryNotificationExpandedId)
+ this._summaryNotificationExpandedId = this._summaryNotification.connect('expanded',
+ Lang.bind(this, this._onSummaryBoxPointerExpanded));
+ this._summaryNotification.expand(false);
+ } else if (this._clickedSummaryItemMouseButton == 3) {
+ this._summaryRightClickMenuClickedId = this._clickedSummaryItem.connect('right-click-menu-done-displaying',
+ Lang.bind(this, this._escapeTray));
+ this._summaryBoxPointer.bin.child = this._clickedSummaryItem.rightClickMenu;
+ }
- this._summaryNotificationBoxPointer.bin.child = this._summaryNotification.actor;
- this._focusGrabber.grabFocus(this._summaryNotification.actor);
+ this._focusGrabber.grabFocus(this._summaryBoxPointer.bin.child);
- if (!this._summaryNotificationExpandedId)
- this._summaryNotificationExpandedId = this._summaryNotification.connect('expanded', Lang.bind(this, this._onSummaryNotificationExpanded));
- this._summaryNotification.expand(false);
this._clickedSummaryItemAllocationChangedId =
this._clickedSummaryItem.actor.connect('allocation-changed',
- Lang.bind(this, this._adjustNotificationBoxPointerPosition));
+ Lang.bind(this, this._adjustSummaryBoxPointerPosition));
// _clickedSummaryItem.actor can change absolute postiion without changing allocation
this._summaryMotionId = this._summary.connect('allocation-changed',
- Lang.bind(this, this._adjustNotificationBoxPointerPosition));
+ Lang.bind(this, this._adjustSummaryBoxPointerPosition));
- this._summaryNotificationBoxPointer.actor.opacity = 0;
- this._summaryNotificationBoxPointer.actor.show();
- this._adjustNotificationBoxPointerPosition();
+ this._summaryBoxPointer.actor.opacity = 0;
+ this._summaryBoxPointer.actor.show();
+ this._adjustSummaryBoxPointerPosition();
- this._summaryNotificationState = State.SHOWING;
- this._summaryNotificationBoxPointer.show(true, Lang.bind(this, function() {
- this._summaryNotificationState = State.SHOWN;
+ this._summaryBoxPointerState = State.SHOWING;
+ this._summaryBoxPointer.show(true, Lang.bind(this, function() {
+ this._summaryBoxPointerState = State.SHOWN;
}));
},
- _adjustNotificationBoxPointerPosition: function() {
+ _adjustSummaryBoxPointerPosition: function() {
// The position of the arrow origin should be the same as center of this._clickedSummaryItem.actor
if (!this._clickedSummaryItem)
return;
- this._summaryNotificationBoxPointer.setPosition(this._clickedSummaryItem.actor, 0, 0.5);
+ this._summaryBoxPointer.setPosition(this._clickedSummaryItem.actor, 0, 0.5);
},
_unsetClickedSummaryItem: function() {
this._summaryMotionId = 0;
}
+ if (this._summaryRightClickMenuClickedId) {
+ this._clickedSummaryItem.disconnect(this._summaryRightClickMenuClickedId);
+ this._summaryRightClickMenuClickedId = 0;
+ }
+
this._clickedSummaryItem = null;
+ this._clickedSummaryItemMouseButton = -1;
},
- _onSummaryNotificationExpanded: function() {
- this._adjustNotificationBoxPointerPosition();
+ _onSummaryBoxPointerExpanded: function() {
+ this._adjustSummaryBoxPointerPosition();
},
- _hideSummaryNotification: function() {
+ _hideSummaryBoxPointer: function() {
if (this._summaryNotificationExpandedId) {
this._summaryNotification.disconnect(this._summaryNotificationExpandedId);
this._summaryNotificationExpandedId = 0;
this._unsetClickedSummaryItem();
this._focusGrabber.ungrabFocus();
- this._summaryNotificationState = State.HIDING;
- this._summaryNotificationBoxPointer.hide(true, Lang.bind(this, this._hideSummaryNotificationCompleted));
- },
-
- _hideSummaryNotificationCompleted: function() {
- this._summaryNotificationState = State.HIDDEN;
- this._summaryNotificationBoxPointer.bin.child = null;
- this._summaryNotification.collapseCompleted();
- this._summaryNotification.disconnect(this._summaryNotificationClickedId);
- this._summaryNotificationClickedId = 0;
- let summaryNotification = this._summaryNotification;
- this._summaryNotification = null;
- if (summaryNotification.isTransient && !this._reNotifyWithSummaryNotificationAfterHide)
- summaryNotification.destroy(NotificationDestroyedReason.EXPIRED);
- if (this._reNotifyWithSummaryNotificationAfterHide) {
- this._onNotify(summaryNotification.source, summaryNotification);
- this._reNotifyWithSummaryNotificationAfterHide = false;
+ this._summaryBoxPointerState = State.HIDING;
+ this._summaryBoxPointer.hide(true, Lang.bind(this, this._hideSummaryBoxPointerCompleted));
+ },
+
+ _hideSummaryBoxPointerCompleted: function() {
+ this._summaryBoxPointerState = State.HIDDEN;
+ this._summaryBoxPointer.bin.child = null;
+ if (this._summaryNotification != null) {
+ this._summaryNotification.collapseCompleted();
+ this._summaryNotification.disconnect(this._summaryNotificationClickedId);
+ this._summaryNotificationClickedId = 0;
+ let summaryNotification = this._summaryNotification;
+ this._summaryNotification = null;
+ if (summaryNotification.isTransient && !this._reNotifyWithSummaryNotificationAfterHide)
+ summaryNotification.destroy(NotificationDestroyedReason.EXPIRED);
+ if (this._reNotifyWithSummaryNotificationAfterHide) {
+ this._onNotify(summaryNotification.source, summaryNotification);
+ this._reNotifyWithSummaryNotificationAfterHide = false;
+ }
}
if (this._clickedSummaryItem)
this._updateState();
icon_size: this.ICON_SIZE });
},
- _notificationClicked: function() {
+ open: function() {
this.destroy();
}
};